package com.geor.gcv.core.extract;

import java.util.ArrayList;
import java.util.List;

import org.nutz.log.Loggers;
import org.opencv.core.Mat;
import org.slf4j.Logger;

import com.geor.gcv.core.mat.Mats;
import com.geor.gcv.core.model.Area;

/**
 * logo提取
 * 
 * @author geor.lusongnan
 *
 */
public class LogoExtractor extends AbstractOutLineExtractor {
	private Extractor extractor;
	private static Logger log = Loggers.get();
	private List<Area> codeAreas;

	public LogoExtractor(Extractor extractor, int addWidth, int addHeight) {
		super(addWidth, addHeight);
		this.extractor = extractor == null ? new CodeExtractor(0.6f) : extractor;
	}

	Mat mat;

	@Override
	public void execute(Mat step) {
		mat = step.clone();
		// 先得到LOGO可能出现的区域
		extractor.execute(step.clone());
		if (null == codeAreas || codeAreas.isEmpty()) {
			log.debug("logo extract no support!");
		}
		codeAreas = extractor.get();
		super.execute(step);
		// 合并重叠区域
		// MergerOfOverlap();
		Mats.releseMat(mat);
	}

	protected void MergerOfOverlap() {
		if (null == get() || get().isEmpty() || get().size() < 2) {
			return;
		}

		List<Area> lists1 = new ArrayList<Area>();
		List<Area> lists2 = new ArrayList<Area>();

		lists1.addAll(get());
		lists2.addAll(get());

		List<Area> mergeAreas = new ArrayList<Area>();
		for (int i = 0; i < lists1.size() - 1; i++) {
			Area area = lists1.get(i);
			if (area == null)
				continue;
			// 需要合拼的区域集合
			List<Area> temps = new ArrayList<Area>();
			temps.add(area);
			lists1.set(i, null);
			lists2.set(i, null);
			for (int j = i + 1; j < lists2.size(); j++) {
				Area readyArea = lists2.get(j);
				if (readyArea == null)
					continue;
				// 重叠?
				if (Mats.coincidence(area, readyArea)) {
					temps.add(readyArea);
					lists1.set(j, null);
					lists2.set(j, null);
				}
			}
			// 合并区域集合
			mergeAreas.add(Mats.mergerArea(temps));
		}

		// 判断是否是最后一个是否重叠，防止遗漏了区域
		Area finalArea = get().get(get().size() - 1);
		boolean flag = false;
		for (int i = 0; i < mergeAreas.size(); i++) {
			// 看看最后一个是不是重叠了
			if (Mats.coincidence(mergeAreas.get(i), finalArea)) {
				flag = true;
				// 设置最后一个合并的区域
				mergeAreas.set(i, Mats.mergerArea(mergeAreas.get(i), finalArea));
				break;
			}
		}
		// 没有重叠
		if (!flag) {
			mergeAreas.add(finalArea);
		}
		areas = mergeAreas;
	}

	@Override
	protected Area filterArea(Area area) {
		if (area.getArea() <= 1000) {
			return null;
		} else if (area.getArea() >= 100000) {
			return null;
		} else if (area.getHeight() > area.getWidth() * 7) {
			return null;
		} else if (area.getHeight() * 7 < area.getWidth()) {
			return null;
		}
		for (Area codeArea : codeAreas) {
			int codeY = codeArea.getY();
			int codeHeight = codeArea.getHeight();
			int codeX = codeArea.getX();
			int codeWidth = codeArea.getWidth();

			int y = area.getY();
			int height = area.getHeight();
			int x = area.getX();
			int width = area.getWidth();

			// 左下角一定要在codeArea高度之内,右上角一定要在codeArea高度之内
			if ((y + height >= codeY && y + height < codeY + codeHeight) || (y > codeY && y < codeY + codeHeight)) {
				// 左上角一定要在codeArea宽度之外,右上角一定要在codeArea宽度之外
				if ((x + width < codeX) || (x > codeX + codeWidth)) {
					return area;
				} else {
					continue;
				}
			} else {
				continue;
			}
		}
		return null;
	}

}
